<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="Eja6Q" id="Eja6Q"><span data-lake-id="u643ecb19" id="u643ecb19">典型回答</span></h1>
  <p data-lake-id="u95ddfc43" id="u95ddfc43"><br></p>
  <p data-lake-id="u2210f1b3" id="u2210f1b3"><span data-lake-id="u9d2fc824" id="u9d2fc824">MySQL的Innodb引擎中，支持多种锁级别，包括了行级锁和表级锁。当多个事务想要访问一个共享资源的时候，如果每个事务都直接请求获取锁，那么就可能会导致互相阻塞，甚至导致死锁。</span></p>
  <p data-lake-id="u6c4e233a" id="u6c4e233a"><span data-lake-id="ue52cfe45" id="ue52cfe45">​</span><br></p>
  <p data-lake-id="u8070443a" id="u8070443a"><span data-lake-id="u17612357" id="u17612357">举个例子：</span></p>
  <p data-lake-id="ueb102232" id="ueb102232"><span data-lake-id="u2ac0c599" id="u2ac0c599">​</span><br></p>
  <blockquote data-lake-id="u93faac76" id="u93faac76">
   <p data-lake-id="u87506828" id="u87506828"><span data-lake-id="ud69e0622" id="ud69e0622">事务A</span><span data-lake-id="u715bd707" id="u715bd707" style="color: rgb(18, 18, 18)">对表Table1中的一行加上了行级锁，这时候这行记录就只能读不能写了。事务B申请对Table1增加了表级锁，如果他申请成功了，那么他就可以修改表中的任意一行记录。这就发生了冲突。</span></p>
   <p data-lake-id="u7da2ce17" id="u7da2ce17"><span data-lake-id="u854b8320" id="u854b8320" style="color: rgb(18, 18, 18)">​</span><br></p>
   <p data-lake-id="u534d9831" id="u534d9831"><span data-lake-id="u6530ff13" id="u6530ff13" style="color: rgb(18, 18, 18)">那么，想要解决这个问题，就需要让事务B在对Table1增加表级锁的时候，先判断一下是不是有事务增加过行级锁。但是，事务B总不能遍历表中数据逐条判断是否有加锁吧？</span></p>
  </blockquote>
  <p data-lake-id="u0a014472" id="u0a014472"><span data-lake-id="ub8082af8" id="ub8082af8" style="color: rgb(18, 18, 18)">​</span><br></p>
  <p data-lake-id="uffbae51e" id="uffbae51e"><span data-lake-id="uf177729e" id="uf177729e" style="color: rgb(18, 18, 18)">所以，为了解决这个问题，</span><span data-lake-id="u82f9e0b7" id="u82f9e0b7">MySQL引入了意向锁机制。</span><strong><span data-lake-id="uaed14f70" id="uaed14f70">​</span></strong></p>
  <p data-lake-id="u5112118e" id="u5112118e"><strong><span data-lake-id="u99ae240a" id="u99ae240a">​</span></strong><br></p>
  <blockquote data-lake-id="u9d828453" id="u9d828453">
   <p data-lake-id="u6246966d" id="u6246966d"><span data-lake-id="u076b827a" id="u076b827a">注意：</span></p>
   <p data-lake-id="ue067c977" id="ue067c977"><span data-lake-id="u84caabfb" id="u84caabfb">1、意向锁并不是直接锁定资源，而是为了通知其他事务，以防止它们在资源上设置不兼容的锁。</span></p>
   <p data-lake-id="u8d100009" id="u8d100009"><span data-lake-id="u690895e1" id="u690895e1">2、意向锁并不是直接由用户请求的，而是由 MySQL 管理的。</span></p>
  </blockquote>
  <p data-lake-id="u4227130b" id="u4227130b"><span data-lake-id="u6ee0e87f" id="u6ee0e87f">​</span><br></p>
  <p data-lake-id="u5a0ea489" id="u5a0ea489"><strong><span data-lake-id="u94d9b0c1" id="u94d9b0c1">当一个事务请求获取一个行级锁或表级锁时，MySQL会自动获取相应的表的意向锁。</span></strong><span data-lake-id="u65951ae9" id="u65951ae9">这样，其他事务请求获取锁时，就可以先基于这个意向锁来发现是否有人加过锁，并根据该锁的类型（意向共享锁/意向排他锁）来判断自己是否可以获取锁。这样可以在不阻塞其他事务的情况下，为当前事务锁定资源。</span></p>
  <p data-lake-id="u58e006d5" id="u58e006d5"><br></p>
  <p data-lake-id="u0cebfa1b" id="u0cebfa1b"><span data-lake-id="uaa7ce266" id="uaa7ce266">意向锁有两种类型：意向共享锁和意向排他锁。</span><strong><span data-lake-id="u886160a0" id="u886160a0">​</span></strong></p>
  <p data-lake-id="u626bf180" id="u626bf180"><strong><span data-lake-id="u88abdd51" id="u88abdd51">​</span></strong><br></p>
  <ol list="ucd305394">
   <li fid="u85ee5dfc" data-lake-id="u6fd77e5f" id="u6fd77e5f" data-lake-index-type="true"><strong><span data-lake-id="u2bf4e65e" id="u2bf4e65e">意向共享锁</span></strong><span data-lake-id="u1066f498" id="u1066f498">： 表示事务打算在资源上设置共享锁</span><strong><span data-lake-id="ub574e8c6" id="ub574e8c6">（读锁）</span></strong><span data-lake-id="u06a20df1" id="u06a20df1">。这通常用于表示事务计划读取资源，并不希望在读取时有其他事务设置排它锁。</span></li>
   <li fid="u85ee5dfc" data-lake-id="u92eebd78" id="u92eebd78" data-lake-index-type="true"><strong><span data-lake-id="u28cf645a" id="u28cf645a">意向排它锁</span></strong><span data-lake-id="u2fab9333" id="u2fab9333">： 表示事务打算在资源上设置排它锁</span><strong><span data-lake-id="ued5abbe8" id="ued5abbe8">（写锁）</span></strong><span data-lake-id="u7d10cabe" id="u7d10cabe">。这表示事务计划修改资源，并不希望有其他事务同时设置共享或排它锁。</span></li>
  </ol>
  <p data-lake-id="u30a67241" id="u30a67241"><span data-lake-id="u14897a79" id="u14897a79">​</span><br></p>
  <p data-lake-id="uf2e997a9" id="uf2e997a9"><strong><span data-lake-id="u43f5ca7e" id="u43f5ca7e">意向锁是一个表级锁，并且他会在触发意向锁的事务提交或者回滚后释放。</span></strong></p>
  <p data-lake-id="ubcfcda58" id="ubcfcda58"><span data-lake-id="uafd10ae1" id="uafd10ae1">​</span><br></p>
 </body>
</html>